#-*- coding:utf-8 -*-
"""
@Time:2020/9/420:54
@Auth:DaiXvWen
@File:views.py
********************Flask的视图文件***********************
"""
#视图文件

from flask import render_template
from FlaskPro.OA import oa  #导入OA文件夹下的init中的oa对象
from FlaskPro.OA.models import Person,Department,Position,db,News,Attendance,Permission
from flask import request
from flask import session  #使用session需要导包，请求上下文
import functools  #保留原函数名
from flask import redirect   #重定向
import os
import hashlib
import datetime
#后端校验导包
from .form import RegisterForm,AddPersonForm,AddDepartmentForm  #导入RegisterForm

def tupianpj(name):
    # 上传图片
    img = request.files.get(name)

    # 获取图片的名字
    imgname = img.filename

    # 保存图片-图片存储路径
    # 数据库存储路径
    db_path = os.path.join("img", imgname)
    # 项目目录，打开当前文件的上一级目录
    file_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

    # static所在目录
    static_path = os.path.join(file_path, "static")

    # 图片存储路径
    save_path = os.path.join(static_path, db_path)
    # 图片保存
    img.save(save_path)



#编写加密函数，很重要
def setpassword(pwd):
    md5=hashlib.md5()
    md5.update(pwd.encode())
    result=md5.hexdigest()
    return result


#写一个登录装饰器
#将装饰器放在路由下面
def LoginValid(func):
    #保留原来的函数名
    @functools.wraps(func)   #解决装饰器导致函数名全都变成一样的问题（flask中不予许有相同的函数名）
    def inner(*args,**kwargs):  #*args接收多个参数  ****kwargs接收字典
        #校验是否登录,使用cookie和session校验
        cookie_name = request.cookies.get("name")  #拿到cookie
        #拿到session
        session_name=session.get("name")
        if cookie_name and session_name and cookie_name==session_name:
        #登录
        #返回函数执行结果
            return func(*args,**kwargs)  #指向调用函数的返回值，指向其返回结果
        #未登录
        return redirect("/login")
        # return func(*args,**kwargs)
    return inner

@oa.route("/")
@LoginValid
def home():

    return render_template("index.html")

@oa.route("/profile")
@LoginValid
def profile():
    #获取登陆者的信息
    data = request.cookies["name"]
    person = Person.query.filter(Person.username==data).first()


    return render_template("profile.html",**locals())


@oa.route("/login",methods=["GET","POST"])
def login():

    #编写登录校验
    if request.method=="POST":
        data=request.form
        # print(data)
        #拿到发送的username和password
        name=request.form.get("username")
        password=request.form.get("password")
        #判断是否为空
        if name and password:
            ##校验数据
            user=Person.query.filter(Person.username==name,Person.password==setpassword(password)).first()
            if user:
                # 用户存在
                response = redirect("/index")  #校验成功重定向到index界面
                #cookie与session设置要依赖于响应对象
                #设置cookie
                response.set_cookie("name",name)
                #获取cookie
                # name=request.cookies.get(name)

                #设置session
                session["name"]=name
                #获取session
                # s_name=session.get("name")

                return response #跳转界面到index
            else:
                #用户不存在

                message="用户名或者密码错误"
                return render_template("login.html",**locals())
        return render_template("login.html", **locals())  #没有输入账号密码，返回login界面
    return render_template("login.html",**locals())

    # return "登录成功"

@oa.route("/logout")
def logout():
    # return redirect("/login")
    ##删除cookie和session
    response=redirect("/login")
    #删除cookie，就是重新下发一个空值覆盖掉之前的cookies
    response.delete_cookie("name")
    # 删除session
    del session["name"]
    return response

#部门渲染
@oa.route("/department",methods=["GET","POST"])
@LoginValid
def department():
    department_list = Department.query.all()
    #删除部门
    data=request.args
    department=Department.query.get(data.get("id"))
    if department:
        department.delete()
        return redirect("/department")

    return render_template("department.html", **locals())


@oa.route("/detail_news",methods=["GET","POST"])
@LoginValid
def detail_news():
    data=request.args
    news=News.query.filter(News.id==data.get("id")).first()



    return render_template("detail_news.html", **locals())


@oa.route("/news",methods=["GET","POST"])
@LoginValid
def news():
    news_list=News.query.all()
    delete_id=request.args.get("id")
    news=News.query.get(delete_id)
    if news:
        news.delete()
        return redirect("/news")

    return render_template("news.html", **locals())


@oa.route("/detail")
@LoginValid
def detail():
    return render_template("detail.html")


@oa.route("/edit_base")
@LoginValid
def edit_base():
    return render_template("edit_base.html")

#职位渲染
@oa.route("/position",methods=["GET","POST"])
@LoginValid
def position():
    data=request.args
    # print(data)
    # print(data)  #ImmutableMultiDict([('id', '1')])
    position_list=Position.query.filter(Position.p_department==data["id"]).all()
    department=Department.query.get(data.get("id"))
    #添加职位
    if request.method=="POST":
        data1=request.form
        pos=Position(p_name=request.form.get("name"),
                     p_level=request.form.get("level"),
                     p_department=data.get("id")
                     )
        pos.save()
        return redirect("/position?id={}".format(data.get("id")))

    return render_template("position.html",**locals())


#职位编辑
@oa.route("/edit_position",methods=["GET","POST"])
@LoginValid
def edit_position():
    pos_id = request.form.get("pos_id")
    pos = Position.query.get(pos_id)
    print(request.form)
    # 编辑职位
    if request.method == "POST":
        pos.p_name=request.form.get("name"),
        pos.p_level=request.form.get("level"),
        pos.update()

    return redirect("/position?id={}".format(pos.p_department))


#删除职位
@oa.route("/delete_position")
@LoginValid
def delete_position():
    # print(request.args)
    pos_id=request.args.get("pos_id")
    pos_del=Position.query.get(pos_id)
    pos_del.delete()
    return "delete"

#关联职位
@oa.route("/position_permission/<int:id>",methods=["GET","POST"])
@LoginValid
def position_permission(id):
    position=Position.query.all()
    # 获取权限
    # print(id)
    perm = Permission.query.filter(Permission.id == id).first()
    if request.method=="POST":
        print(request.form)
        #get方法只能拿到一个position_ids的值，因为name都是相同的
        #使用getlist方法
        position_ids = request.form.getlist("position_ids")
        # 关联关系   多对多的情况 多对多的增加数据
        pos_list = []
        for pos_id in position_ids:
            pos = Position.query.filter(Position.id == int(pos_id)).first()
            pos_list.append(pos)
        perm.p_position = pos_list
        perm.save()
        return redirect("/permission")

    return render_template("position_permission.html",**locals())


#考勤界面管理
@oa.route("/attendance_me",methods=["GET","POST"])
@LoginValid
def attendance_me():
    # 拿到登陆者的名字
    username = request.cookies.get("name")
    person = Person.query.filter(Person.username == username).first()

    ## 无审核人版本，可以看到假条的都可以申请
    # if request.method=="POST":
    #     #保存数据
    #     ad = Attendance()
    #     ad.reason = request.form.get("reason")
    #     ad.a_type = request.form.get("type")
    #     ad.days = request.form.get("day")
    #
    #     ad.start_time = datetime.datetime.strptime(request.form.get("start"), "%Y-%m-%d %H:%M:%S")
    #     ad.end_time = datetime.datetime.strptime(request.form.get("end"), "%Y-%m-%d %H:%M:%S")
    #
    #     # 申请人
    #     ad.user = person.id
    #     # 审核人，无
    #     ad.examine = ""
    #     ad.save()



    ##人事部门的人员可以审核
    if request.method=="POST":
        #保存数据
        ad = Attendance()
        ad.reason = request.form.get("reason")
        ad.a_type = request.form.get("type")
        ad.days = request.form.get("day")

        ad.start_time = datetime.datetime.strptime(request.form.get("start"), "%Y-%m-%d %H:%M:%S")
        ad.end_time = datetime.datetime.strptime(request.form.get("end"), "%Y-%m-%d %H:%M:%S")

        # 申请人
        ad.user = person.id
        # 审核人，人事部门人员
        #拿到人事部
        dep=Department.query.filter(Department.d_name=="人事部").first()
        #拿到人事部level=1对应的职位
        pos=Position.query.filter(Position.p_level==1,Position.p_department==dep.id).first()
        #查询人事部门下的人员
        ex_user = Person.query.filter(Person.p_position == pos.id).first()
        print(pos)
        #添加到数据库
        ad.examine = ex_user.username
        ad.save()

    # 渲染数据显示
    user=Person.query.filter(Person.username==username).first()
    ad_list=Attendance.query.filter(Attendance.user==user.id).all()

    return render_template("attendance_me.html",**locals())

#下属考勤
@oa.route("/attendance_subordinate")
@LoginValid
def attendance_subordinate():
    att_per_list=[]
    data=request.cookies.get("name")
    #拿到登录角色的person对象
    person=Person.query.filter(Person.username==data).first()
    #拿到对应的dep
    p_dep=person.our_position.p_depart  #id=4的department
    #拿到登陆账号下对应的职位等级
    pos_level=person.our_position.p_level
    # print(pos_level)  #5
    #拿到level等级低于登录账号的用户
    pos_list=Position.query.filter(Position.p_department==p_dep.id,Position.p_level<pos_level).all()
    # print(pos)  #4个对象
    #通过4个position再去找人
    for i in pos_list:
        person_list=Person.query.filter(Person.p_position==i.id).all()
        for j in person_list:
            att_per_list.append(j)
    att_under_list=[]
    for k in att_per_list:
        att_under=Attendance.query.filter(Attendance.user==k.id).all()
        for m in att_under:
            att_under_list.append(m)


    return render_template("attendance_subordinate.html",**locals())

#编写通过与驳回的路由
@oa.route("/update_attendance_subordinate/<int:status>/<int:id>")
@LoginValid
def update_attendance_subordinate(status,id):
    #假条id
    ad=Attendance.query.filter(Attendance.id==id).first()
    #审核人id
    per_name=request.cookies.get("name")
    person=Person.query.filter(Person.username==per_name).first()
    if status==1:
        #通过
        ad.status=1
    elif status==2:
        #驳回
        ad.status=2
    ad.examine=person.username
    ad.save()

    return redirect("/attendance_subordinate")

#编辑修改用户信息
@oa.route("/edit_person/<id>",methods=["GET","POST"])
@LoginValid
def edit_person(id):
    p=Person.query.get(id)
    # 判断是不是POST请求
    if request.method == "POST":
        # username = request.form.get("username")
        # user = Person.query.filter(Person.username == username).first()
        # if user is None:
        #     # 接收并提交POST请求
        #     # print(request.form)

        p.username = request.form.get("username")
        p.password = request.form.get("password")
        p.nickname = request.form.get("nickname")
        p.age = request.form.get("age")
        p.gender = request.form.get("gender")
        p.email = request.form.get("email")
        p.address = request.form.get("address")

        # 使用图片拼接函数
        tupianpj('photo')

        # 上传图片
        img = request.files.get('photo')
        # 获取图片的名字
        imgname = img.filename

        # 数据库存储图片
        news.picture = os.path.join("img", imgname)

        p.update()

        # 提交后重定向到/person页面
        return redirect("/person")


    return render_template("edit_person.html",**locals())

#增加权限
@oa.route("/add_permission",methods = ["GET","POST"])
@LoginValid
def add_permission():
    # get 请求 获取页面
    # post 请求 获取数据  添加数据
    if request.method=="POST":
        perm = Permission()
        perm.per_name = request.form.get("name")
        perm.per_desc = request.form.get("description")
        perm.save()
        # 重定向
        return redirect("/permission")

    return render_template("add_permission.html")



@oa.route("/add_person",methods=["GET","POST"])
@LoginValid
def add_person():
    addpersonform = AddPersonForm()
    #判断是不是POST请求
    if request.method=="POST":
        username=request.form.get("username")
        user=Person.query.filter(Person.username==username).first()
        #判断用户名是否重复并且合格
        if user is None and addpersonform.validate_on_submit():
            #接收并提交POST请求
            person = Person()
            person.username = request.form.get("username")
            person.password = setpassword(request.form.get("password"))
            person.nickname = request.form.get("nickname")
            person.age = request.form.get("age")
            person.gender = request.form.get("gender")
            person.email = request.form.get("email")
            person.address = request.form.get("address")

            person.p_position = 1
            #获取图片信息
            img = request.files.get("photo")
            # print(img)
            if img:
                # 使用图片拼接函数
                tupianpj('photo')

                # 上传图片
                img = request.files.get('photo')
                # 获取图片的名字
                imgname = img.filename

                # 数据库存储图片
                person.photo = os.path.join("img", imgname)

            #保存数据
            person.save()

            #提交后重定向到/person页面
            return redirect("/person")
        else:
            #打印报错
            errors = addpersonform.errors
            print(errors)


    return render_template("add_person.html",**locals())



@oa.route("/edit_permission",methods=["GET","POST"])
@LoginValid
def edit_permission():
    permission_id=request.args.get("permission_id")
    per=Permission.query.get(permission_id)
    if request.method=="POST":
        per.per_name=request.form.get("name")
        per.per_desc=request.form.get("description")
        per.update()

        return redirect("/permission")

    return render_template("edit_permission.html",**locals())


#编写首页echarts的api
@oa.route("/echarts_api")
@LoginValid
def echarts_api():
    result={
       "data":[]
    }
    dep_list=Department.query.all()
    for dep in dep_list:
        dep_person_num = 0   # 每个部门下面的人数
        pos_list=dep.d_position #使用反向映射查找position
        for pos in pos_list:
            person_num=len(pos.p_person)   #使用返现映射拿到全部的person
            dep_person_num += person_num
        result_dict={
            "name":dep.d_name,
            "num":dep_person_num
        }
        result["data"].append(result_dict)  #将数据添加入result

    return result

@oa.route("/index")
@LoginValid
def index():
    data=request.cookies["name"]


    return render_template("index.html",**locals())



@oa.route("/person",methods=["GET","POST"])
@LoginValid
def person():

    #拿到页面参数
    page = request.args.get("page")
    #进行page判定
    if page is None:
        page = 1
    else:
        page = int(page)

    #使用paginate进行分页，一页10条数据
    page_size = 10
    person_obj = Person.query.paginate(page, page_size)

    #拿到迭代后的多条对象
    # person_list = person_obj.items

    #页面栏显示五页，选中的一页排在中间，被显示被选中
    #如 1 2 ‘3’ 4 5
    #   3 4 ‘5’ 6 7
    #拿到总页数
    count_page=person_obj.pages
    #当总页数小于等于5时
    if count_page<=5:
        start=1
        end=person_obj.pages+1
        page_list = range(start, end)
    else:
        if page <= 3:
            start = 1
            end = start + 5
        elif page >= person_obj.pages - 2:
            start = person_obj.pages - 4
            end = person_obj.pages + 1
        else:
            start = page - 2
            end = page + 3
        page_list = range(start, end)  # 3  4 5 6 7

    person_list = []
    data = request.args

    #返回后台数据-用户信息
    d=Department.query.get(data.get("id"))  #拿到对应id的部门

    if d is None:
        person_list=person_obj.items

    else:

        p_id = Position.query.filter(Position.p_department == int(data.get("id")))
        for i in p_id:
            k = Person.query.filter(Person.p_position == i.id).all()
            for j in k:
                person_list.append(j)


    #循环拿到部门名
    department_list=Department.query.all()


    #获取请求参数
    person_username=data.get("person_username")
    if person_username:
        person_list=Person.query.filter(Person.username.like("%{}%".format(person_username))).all()


    return render_template("person.html",**locals())  #**locals()收集这个函数中的所有变量，进行解包传参

#权限管理界面展示
@oa.route("/permission")
@LoginValid
def permission():

    permission_list = Permission.query.all()
    #删除某一个权限
    permission_id=request.args.get("permission_id")
    if permission_id:
        per=Permission.query.get(permission_id)
        per.delete()
        return redirect("/permission")

    return render_template("permission.html",**locals())


@oa.route("/add_news",methods=["GET","POST"])
@LoginValid
def add_news():
    # 判断是不是POST请求
    if request.method == "POST":
        # print(request.form)
        news=News(title=request.form.get('title'),
                  author=request.form.get('author'),
                  content=request.form.get('content'),
                  public_time=datetime.date.today()
        )
        #使用图片拼接函数
        tupianpj('picture')

        # 上传图片
        img = request.files.get('picture')
        # 获取图片的名字
        imgname = img.filename

        # 数据库存储图片
        news.picture = os.path.join("img", imgname)
        news.save()
        # 提交后重定向到/person页面
        return redirect("/news")

    # # 接收并提交POST请求
    # print(request.form)

    return render_template("add_news.html")


@oa.route("/edit_news",methods=["GET","POST"])
@LoginValid
def edit_news():
    edit_id = request.args.get("id")
    news=News.query.get(edit_id)
    #判断提交按钮
    if request.method=="POST":
        news.author = request.form.get("author")
        news.title = request.form.get("title")
        news.content = request.form.get("content")
        news.public_time = datetime.date.today()

        tupianpj('picture')

        # 上传图片
        img = request.files.get('picture')
        # 获取图片的名字
        imgname = img.filename

        # 数据库存储图片
        news.picture = os.path.join("img", imgname)
        news.update()

        return redirect("/news")

    return render_template("edit_news.html",**locals())

#添加部门
@oa.route("/add_department",methods=["GET","POST"])
@LoginValid
def add_department():
    # 判断是不是POST请求
    if request.method == "POST":
        dep = request.form
        # print(dep)
        #ImmutableMultiDict([('csrf_token', 'IjIyZjA5NzY2MjI4MGZiMDc3OGQ0ZTg2ZTdiOGZkYTM5NTExNzFkODQi.XrNnMQ.nbDY_muilkOeESA03_NSXHBY_fU'), ('name', '123'), ('description', '123')])
        dep1=dep.to_dict() #转换为字典类型
        # print(dep1)
        del dep1['csrf_token'] #删除csrf_token
        # print(dep1) {'name': '1234', 'description': '1234'}

        d_name = request.form.get("name")
        department = Department.query.filter(Department.d_name == d_name).first()
        if department is None:  #判断添加的部门是否存在

            department = Department(**dep1)  #打开数据库
            department.save()
        return redirect("/department")

    return render_template("add_department.html",**locals())

##部门管理，编辑
@oa.route("/edit_department",methods=["GET","POST"])
@LoginValid
def edit_department():

    data_id=request.args.get("id")

    department=Department.query.filter(Department.id==data_id).first() #拿到对应的部门

    if request.method == "POST":
        dep = request.form

        department.d_name=dep.get("d_name")
        department.d_description=dep.get("d_description")
        department.update()
        return redirect("/department")

    return render_template("edit_department.html",**locals())

#职员管理详情
@oa.route("/detail_person/<id>")
@LoginValid
def detail_person(id):
    p=Person.query.get(id)
    # print(p)

    return render_template("detail_person.html",**locals())

#建立p_list网站的路由
# /<string:dep>/<int:page>/
# dep,page

@oa.route("/p_list")
@LoginValid
def p_list1():
    department_list = db.session.query(Person.departemt).group_by(Person.departemt).all()
    department_list= [i[0] for i in department_list]
    return render_template("p_list.html",**locals())


@oa.route("/p_list/<string:dep>/<int:page>/")
def p_list(dep,page):
    """
    每页10条
    :param dep:
    :param page:
    :return:
    """
    #模糊查询

    # name1=request.args.get("person_username")
    # print(name1)
    # url1='/p_list/'+name1+'/1'
    # p_like=Person.query.filter(Person.name.like("%{}%".format(name1)))  #拿到了模糊查询的结果
    # print(p_like)

    #departemt写错了，注意
    department_list = db.session.query(Person.departemt).group_by(Person.departemt).all()
    department_list = [i[0] for i in department_list]
    page_size = 10
    offset = (page-1)*page_size
    person_list = Person.query.filter(Person.departemt == dep).limit(10).offset(offset)
    # person_list1 = Person.query.filter(Person.departemt == dep)
    # count=0
    # for j in person_list1:
    #     count+=1
    #
    # mk=count//25+1

    return render_template("p_list.html",**locals())


@oa.route("/delete1/<id>")
def delete1(id):
    p= Person.query.get(id)
    p.delete()

    return redirect("/person")

#后端校验

#注册路由
@oa.route("/register1",methods=["GET","POST"])
def register1():
    #实例化视图
    registerform=RegisterForm()
    if request.method=="POST":
        print(request.form)
        # validate_on_submit()将数据提交给form类进行校验
        if registerform.validate_on_submit():  #将提交的数据，交给forms类进行后端校验
            #True代表通过
            print("success")
        else:
            # False 校验不通过
            print("error")
            #打印失败的信息
            errors=registerform.errors
            print(errors)

    return render_template("register1.html",**locals())

@oa.route("/123456",methods=["GET","POST"])
def fenye1():
    person_obj=Person.query.paginate(1,10)
    print(person_obj)
    data=person_obj.items
    print(data)
    #数据总量
    print(person_obj.total)

    print(person_obj.page)

    print(person_obj.iter_pages)  #迭代得到一个对象
    for one in person_obj.iter_pages():   #加上括号代表执行
        print(one)



    return "查询成功"